#include "QPropertyFactoryManager.h"
#include "private/QPropertyFactoryManager_p.h"

#include "QStandardPropertyFactory.h"
#include "QProperty.h"

using namespace QPE;


QPropertyFactoryManager* QPropertyFactoryManager::DefaultManager = NULL;

QPropertyFactoryManager::QPropertyFactoryManager(QObject *parent)
	: QObject(parent), d_ptr(new QPropertyFactoryManagerPrivate())
{

}

QPropertyFactoryManager::~QPropertyFactoryManager()
{
	// Delete all factories
	QList<QAbstractPropertyFactory*> tmpFactories = d_ptr->Factories.values();
	while(!tmpFactories.isEmpty()) {
		QAbstractPropertyFactory* tmpFactory = tmpFactories.takeLast();
		tmpFactories.removeAll(tmpFactory);
		delete tmpFactory;
	}


	delete d_ptr;
	if(this == DefaultManager)
		DefaultManager = NULL;
}

void QPropertyFactoryManager::registerFactory(const QString& type, QAbstractPropertyFactory* factory)
{
	if(type.isEmpty())
		return;

	// Remove old factory
	unregisterFactory(getFactory(type), type, true);
	// Register new one
	d_ptr->Factories[type] = factory;
}

void QPropertyFactoryManager::unregisterFactory(QAbstractPropertyFactory* factory, const QString& type, bool delete_if_unused)
{
	if(!factory)
		return;

	if(!type.isEmpty()) {
		// Remove all occurances
		QString tmpKey;
		do {
			tmpKey = d_ptr->Factories.key(factory, QString());
			if(!tmpKey.isEmpty()) d_ptr->Factories.remove(tmpKey);
		} while(!tmpKey.isEmpty());
	} else {
		// Only remove one type
		if(d_ptr->Factories.value(type, NULL) == factory)
			d_ptr->Factories.remove(type);
	}

	if(delete_if_unused && !isRegistered(factory))
		delete factory;
}

bool QPropertyFactoryManager::isRegistered(QAbstractPropertyFactory* factory)
{
	return (!d_ptr->Factories.key(factory, QString()).isEmpty());
}

QAbstractPropertyFactory* QPropertyFactoryManager::getFactory(const QString& type)
{
	return d_ptr->Factories.value(type, NULL);
}


QProperty* QPropertyFactoryManager::createProperty(const QString& type, const QString& name, const QString& description, const QString &default_value)
{
	QAbstractPropertyFactory* tmpFactory = getFactory(type);
	QProperty* tmpResult = NULL;
	if(tmpFactory) {
		tmpResult = tmpFactory->createProperty(type, name);

		if(tmpResult) {
			tmpResult->setDescription(description);

			if(!default_value.isEmpty())
				tmpResult->deserialize(default_value);
		}
	}

	return tmpResult;
}

QPropertyFactoryManager *QPropertyFactoryManager::getDefaultManager()
{
	if(!DefaultManager) {
		DefaultManager = new QPropertyFactoryManager();
		/*QStandardPropertyFactory* tmpStandardProp = */new QStandardPropertyFactory(DefaultManager);
	}

	return DefaultManager;
}

QStringList QPropertyFactoryManager::getSupportedTypes()
{
	return d_ptr->Factories.keys();
}
